mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-02-28 09:27:38 +01:00
Move api client configuration to separate data class.
Signed-off-by: Yahor Berdnikau <egorr.berd@gmail.com>
This commit is contained in:
parent
52b32d0fd6
commit
8dc9534327
@ -21,8 +21,14 @@ class GetStreamUrlTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
client = SubsonicAPIClient(mockWebServerRule.mockWebServer.url("/").toString(),
|
val config = SubsonicClientConfiguration(
|
||||||
USERNAME, PASSWORD, V1_6_0, CLIENT_ID)
|
mockWebServerRule.mockWebServer.url("/").toString(),
|
||||||
|
USERNAME,
|
||||||
|
PASSWORD,
|
||||||
|
V1_6_0,
|
||||||
|
CLIENT_ID
|
||||||
|
)
|
||||||
|
client = SubsonicAPIClient(config)
|
||||||
val baseExpectedUrl = mockWebServerRule.mockWebServer.url("").toString()
|
val baseExpectedUrl = mockWebServerRule.mockWebServer.url("").toString()
|
||||||
expectedUrl = "$baseExpectedUrl/rest/stream.view?id=$id&u=$USERNAME" +
|
expectedUrl = "$baseExpectedUrl/rest/stream.view?id=$id&u=$USERNAME" +
|
||||||
"&c=$CLIENT_ID&f=json&v=${V1_6_0.restApiVersion}&p=enc:${PASSWORD.toHexBytes()}"
|
"&c=$CLIENT_ID&f=json&v=${V1_6_0.restApiVersion}&p=enc:${PASSWORD.toHexBytes()}"
|
||||||
|
@ -10,11 +10,18 @@ import org.moire.ultrasonic.api.subsonic.rules.MockWebServerRule
|
|||||||
abstract class SubsonicAPIClientTest {
|
abstract class SubsonicAPIClientTest {
|
||||||
@JvmField @Rule val mockWebServerRule = MockWebServerRule()
|
@JvmField @Rule val mockWebServerRule = MockWebServerRule()
|
||||||
|
|
||||||
|
protected lateinit var config: SubsonicClientConfiguration
|
||||||
protected lateinit var client: SubsonicAPIClient
|
protected lateinit var client: SubsonicAPIClient
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
client = SubsonicAPIClient(mockWebServerRule.mockWebServer.url("/").toString(),
|
config = SubsonicClientConfiguration(
|
||||||
USERNAME, PASSWORD, CLIENT_VERSION, CLIENT_ID)
|
mockWebServerRule.mockWebServer.url("/").toString(),
|
||||||
|
USERNAME,
|
||||||
|
PASSWORD,
|
||||||
|
CLIENT_VERSION,
|
||||||
|
CLIENT_ID
|
||||||
|
)
|
||||||
|
client = SubsonicAPIClient(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ import org.junit.Test
|
|||||||
class SubsonicApiPasswordTest : SubsonicAPIClientTest() {
|
class SubsonicApiPasswordTest : SubsonicAPIClientTest() {
|
||||||
@Test
|
@Test
|
||||||
fun `Should pass PasswordMD5Interceptor in query params for api version 1 13 0`() {
|
fun `Should pass PasswordMD5Interceptor in query params for api version 1 13 0`() {
|
||||||
val clientV12 = SubsonicAPIClient(mockWebServerRule.mockWebServer.url("/").toString(),
|
val clientV12 = SubsonicAPIClient(
|
||||||
USERNAME, PASSWORD, SubsonicAPIVersions.V1_14_0, CLIENT_ID)
|
config.copy(minimalProtocolVersion = SubsonicAPIVersions.V1_14_0)
|
||||||
|
)
|
||||||
mockWebServerRule.enqueueResponse("ping_ok.json")
|
mockWebServerRule.enqueueResponse("ping_ok.json")
|
||||||
|
|
||||||
clientV12.api.ping().execute()
|
clientV12.api.ping().execute()
|
||||||
@ -25,8 +26,9 @@ class SubsonicApiPasswordTest : SubsonicAPIClientTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Should pass PasswordHexInterceptor in query params for api version 1 12 0`() {
|
fun `Should pass PasswordHexInterceptor in query params for api version 1 12 0`() {
|
||||||
val clientV11 = SubsonicAPIClient(mockWebServerRule.mockWebServer.url("/").toString(),
|
val clientV11 = SubsonicAPIClient(
|
||||||
USERNAME, PASSWORD, SubsonicAPIVersions.V1_12_0, CLIENT_ID)
|
config.copy(minimalProtocolVersion = SubsonicAPIVersions.V1_12_0)
|
||||||
|
)
|
||||||
mockWebServerRule.enqueueResponse("ping_ok.json")
|
mockWebServerRule.enqueueResponse("ping_ok.json")
|
||||||
|
|
||||||
clientV11.api.ping().execute()
|
clientV11.api.ping().execute()
|
||||||
|
@ -90,7 +90,15 @@ class SubsonicApiSSLTest {
|
|||||||
assertResponseSuccessful(response)
|
assertResponseSuccessful(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSubsonicClient(allowSelfSignedCertificate: Boolean) = SubsonicAPIClient(
|
private fun createSubsonicClient(allowSelfSignedCertificate: Boolean): SubsonicAPIClient {
|
||||||
"https://$HOST:$PORT/", USERNAME, PASSWORD, CLIENT_VERSION, CLIENT_ID,
|
val config = SubsonicClientConfiguration(
|
||||||
allowSelfSignedCertificate = allowSelfSignedCertificate)
|
"https://$HOST:$PORT/",
|
||||||
|
USERNAME,
|
||||||
|
PASSWORD,
|
||||||
|
CLIENT_VERSION,
|
||||||
|
CLIENT_ID,
|
||||||
|
allowSelfSignedCertificate = allowSelfSignedCertificate
|
||||||
|
)
|
||||||
|
return SubsonicAPIClient(config)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,29 +36,23 @@ private const val READ_TIMEOUT = 60_000L
|
|||||||
* @author Yahor Berdnikau
|
* @author Yahor Berdnikau
|
||||||
*/
|
*/
|
||||||
class SubsonicAPIClient(
|
class SubsonicAPIClient(
|
||||||
baseUrl: String,
|
config: SubsonicClientConfiguration
|
||||||
username: String,
|
|
||||||
password: String,
|
|
||||||
minimalProtocolVersion: SubsonicAPIVersions,
|
|
||||||
clientID: String,
|
|
||||||
allowSelfSignedCertificate: Boolean = false,
|
|
||||||
enableLdapUserSupport: Boolean = false,
|
|
||||||
debug: Boolean = false
|
|
||||||
) {
|
) {
|
||||||
private val versionInterceptor = VersionInterceptor(minimalProtocolVersion) {
|
private val versionInterceptor = VersionInterceptor(config.minimalProtocolVersion) {
|
||||||
protocolVersion = it
|
protocolVersion = it
|
||||||
}
|
}
|
||||||
|
|
||||||
private val proxyPasswordInterceptor = ProxyPasswordInterceptor(
|
private val proxyPasswordInterceptor = ProxyPasswordInterceptor(
|
||||||
minimalProtocolVersion,
|
config.minimalProtocolVersion,
|
||||||
PasswordHexInterceptor(password),
|
PasswordHexInterceptor(config.password),
|
||||||
PasswordMD5Interceptor(password),
|
PasswordMD5Interceptor(config.password),
|
||||||
enableLdapUserSupport)
|
config.enableLdapUserSupport
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get currently used protocol version.
|
* Get currently used protocol version.
|
||||||
*/
|
*/
|
||||||
var protocolVersion = minimalProtocolVersion
|
var protocolVersion = config.minimalProtocolVersion
|
||||||
private set(value) {
|
private set(value) {
|
||||||
field = value
|
field = value
|
||||||
proxyPasswordInterceptor.apiVersion = field
|
proxyPasswordInterceptor.apiVersion = field
|
||||||
@ -67,13 +61,13 @@ class SubsonicAPIClient(
|
|||||||
|
|
||||||
private val okHttpClient = OkHttpClient.Builder()
|
private val okHttpClient = OkHttpClient.Builder()
|
||||||
.readTimeout(READ_TIMEOUT, MILLISECONDS)
|
.readTimeout(READ_TIMEOUT, MILLISECONDS)
|
||||||
.apply { if (allowSelfSignedCertificate) allowSelfSignedCertificates() }
|
.apply { if (config.allowSelfSignedCertificate) allowSelfSignedCertificates() }
|
||||||
.addInterceptor { chain ->
|
.addInterceptor { chain ->
|
||||||
// Adds default request params
|
// Adds default request params
|
||||||
val originalRequest = chain.request()
|
val originalRequest = chain.request()
|
||||||
val newUrl = originalRequest.url().newBuilder()
|
val newUrl = originalRequest.url().newBuilder()
|
||||||
.addQueryParameter("u", username)
|
.addQueryParameter("u", config.username)
|
||||||
.addQueryParameter("c", clientID)
|
.addQueryParameter("c", config.clientID)
|
||||||
.addQueryParameter("f", "json")
|
.addQueryParameter("f", "json")
|
||||||
.build()
|
.build()
|
||||||
chain.proceed(originalRequest.newBuilder().url(newUrl).build())
|
chain.proceed(originalRequest.newBuilder().url(newUrl).build())
|
||||||
@ -81,7 +75,7 @@ class SubsonicAPIClient(
|
|||||||
.addInterceptor(versionInterceptor)
|
.addInterceptor(versionInterceptor)
|
||||||
.addInterceptor(proxyPasswordInterceptor)
|
.addInterceptor(proxyPasswordInterceptor)
|
||||||
.addInterceptor(RangeHeaderInterceptor())
|
.addInterceptor(RangeHeaderInterceptor())
|
||||||
.apply { if (debug) addLogging() }
|
.apply { if (config.debug) addLogging() }
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private val jacksonMapper = ObjectMapper()
|
private val jacksonMapper = ObjectMapper()
|
||||||
@ -90,14 +84,15 @@ class SubsonicAPIClient(
|
|||||||
.registerModule(KotlinModule())
|
.registerModule(KotlinModule())
|
||||||
|
|
||||||
private val retrofit = Retrofit.Builder()
|
private val retrofit = Retrofit.Builder()
|
||||||
.baseUrl("$baseUrl/rest/")
|
.baseUrl("${config.baseUrl}/rest/")
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.addConverterFactory(JacksonConverterFactory.create(jacksonMapper))
|
.addConverterFactory(JacksonConverterFactory.create(jacksonMapper))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private val wrappedApi = ApiVersionCheckWrapper(
|
private val wrappedApi = ApiVersionCheckWrapper(
|
||||||
retrofit.create(SubsonicAPIDefinition::class.java),
|
retrofit.create(SubsonicAPIDefinition::class.java),
|
||||||
minimalProtocolVersion)
|
config.minimalProtocolVersion
|
||||||
|
)
|
||||||
|
|
||||||
val api: SubsonicAPIDefinition get() = wrappedApi
|
val api: SubsonicAPIDefinition get() = wrappedApi
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package org.moire.ultrasonic.api.subsonic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides configuration for [SubsonicAPIClient].
|
||||||
|
*/
|
||||||
|
data class SubsonicClientConfiguration(
|
||||||
|
val baseUrl: String,
|
||||||
|
val username: String,
|
||||||
|
val password: String,
|
||||||
|
val minimalProtocolVersion: SubsonicAPIVersions,
|
||||||
|
val clientID: String,
|
||||||
|
val allowSelfSignedCertificate: Boolean = false,
|
||||||
|
val enableLdapUserSupport: Boolean = false,
|
||||||
|
val debug: Boolean = false
|
||||||
|
)
|
@ -7,6 +7,7 @@ import org.koin.dsl.module.applicationContext
|
|||||||
import org.moire.ultrasonic.BuildConfig
|
import org.moire.ultrasonic.BuildConfig
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
||||||
|
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
||||||
import org.moire.ultrasonic.cache.PermanentFileStorage
|
import org.moire.ultrasonic.cache.PermanentFileStorage
|
||||||
import org.moire.ultrasonic.service.CachedMusicService
|
import org.moire.ultrasonic.service.CachedMusicService
|
||||||
import org.moire.ultrasonic.service.MusicService
|
import org.moire.ultrasonic.service.MusicService
|
||||||
@ -68,7 +69,7 @@ fun musicServiceModule(sp: SharedPreferences) = applicationContext {
|
|||||||
password == null
|
password == null
|
||||||
) {
|
) {
|
||||||
Log.i(LOG_TAG, "Server credentials is not available")
|
Log.i(LOG_TAG, "Server credentials is not available")
|
||||||
return@bean SubsonicAPIClient(
|
return@bean SubsonicClientConfiguration(
|
||||||
baseUrl = "http://localhost",
|
baseUrl = "http://localhost",
|
||||||
username = "",
|
username = "",
|
||||||
password = "",
|
password = "",
|
||||||
@ -81,7 +82,7 @@ fun musicServiceModule(sp: SharedPreferences) = applicationContext {
|
|||||||
debug = BuildConfig.DEBUG
|
debug = BuildConfig.DEBUG
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return@bean SubsonicAPIClient(
|
return@bean SubsonicClientConfiguration(
|
||||||
baseUrl = serverUrl,
|
baseUrl = serverUrl,
|
||||||
username = username,
|
username = username,
|
||||||
password = password,
|
password = password,
|
||||||
@ -96,6 +97,8 @@ fun musicServiceModule(sp: SharedPreferences) = applicationContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bean { return@bean SubsonicAPIClient(get()) }
|
||||||
|
|
||||||
bean<MusicService>(name = ONLINE_MUSIC_SERVICE) {
|
bean<MusicService>(name = ONLINE_MUSIC_SERVICE) {
|
||||||
return@bean CachedMusicService(RESTMusicService(get(), get()))
|
return@bean CachedMusicService(RESTMusicService(get(), get()))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user