Refactor io.bartek.ttsserver.web package

This commit is contained in:
2020-05-15 21:36:20 +02:00
parent 79344f9789
commit d95a8ebc17
10 changed files with 89 additions and 55 deletions

View File

@@ -11,7 +11,7 @@ import io.bartek.ttsserver.service.ForegroundNotificationFactory
import io.bartek.ttsserver.sonos.SonosQueue import io.bartek.ttsserver.sonos.SonosQueue
import io.bartek.ttsserver.tts.TTS import io.bartek.ttsserver.tts.TTS
import io.bartek.ttsserver.tts.TTSStatusHolder import io.bartek.ttsserver.tts.TTSStatusHolder
import io.bartek.ttsserver.web.WebServerFactory import io.bartek.ttsserver.web.server.WebServerFactory
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@@ -39,7 +39,12 @@ class TTSModule {
tts: TTS, tts: TTS,
sonos: SonosQueue sonos: SonosQueue
) = ) =
WebServerFactory(preferences, context, tts, sonos) WebServerFactory(
preferences,
context,
tts,
sonos
)
@Provides @Provides
@Singleton @Singleton

View File

@@ -7,8 +7,8 @@ import android.content.SharedPreferences
import android.os.PowerManager import android.os.PowerManager
import dagger.android.DaggerService import dagger.android.DaggerService
import io.bartek.ttsserver.preference.PreferenceKey import io.bartek.ttsserver.preference.PreferenceKey
import io.bartek.ttsserver.web.WebServer import io.bartek.ttsserver.web.server.WebServer
import io.bartek.ttsserver.web.WebServerFactory import io.bartek.ttsserver.web.server.WebServerFactory
import javax.inject.Inject import javax.inject.Inject

View File

@@ -7,7 +7,7 @@ import io.bartek.ttsserver.preference.PreferenceKey
import io.bartek.ttsserver.service.ForegroundService import io.bartek.ttsserver.service.ForegroundService
import io.bartek.ttsserver.service.ServiceState import io.bartek.ttsserver.service.ServiceState
import io.bartek.ttsserver.tts.TTS import io.bartek.ttsserver.tts.TTS
import io.bartek.ttsserver.web.SonosTTSRequestData import io.bartek.ttsserver.web.dto.BaseDTO
import java.util.concurrent.BlockingQueue import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
@@ -15,7 +15,7 @@ private class Consumer(
private val tts: TTS, private val tts: TTS,
private val host: String, private val host: String,
private val port: Int, private val port: Int,
private val queue: BlockingQueue<SonosTTSRequestData> private val queue: BlockingQueue<BaseDTO>
) : Runnable { ) : Runnable {
override fun run() = try { override fun run() = try {
@@ -27,7 +27,7 @@ private class Consumer(
} }
private fun consume(data: SonosTTSRequestData) = private fun consume(data: BaseDTO) =
SonosDiscovery.discover().firstOrNull { it.zoneGroupState.name == data.zone }?.let { SonosDiscovery.discover().firstOrNull { it.zoneGroupState.name == data.zone }?.let {
val file = tts.createTTSFile(data.text, data.language) val file = tts.createTTSFile(data.text, data.language)
val filename = file.name val filename = file.name
@@ -44,7 +44,7 @@ class SonosQueue(
private val networkUtil: NetworkUtil, private val networkUtil: NetworkUtil,
private val preferences: SharedPreferences private val preferences: SharedPreferences
) { ) {
private val queue: BlockingQueue<SonosTTSRequestData> = LinkedBlockingQueue() private val queue: BlockingQueue<BaseDTO> = LinkedBlockingQueue()
private val host: String private val host: String
get() = networkUtil.getIpAddress() get() = networkUtil.getIpAddress()
private val port: Int private val port: Int
@@ -62,5 +62,5 @@ class SonosQueue(
consumer = null consumer = null
} }
fun push(data: SonosTTSRequestData) = queue.add(data) fun push(data: BaseDTO) = queue.add(data)
} }

View File

@@ -1,29 +0,0 @@
package io.bartek.ttsserver.web
import android.content.UriMatcher
import android.net.Uri
enum class Endpoint(val uri: String, val id: Int) {
UNKNOWN("/", 1),
SAY("/say", 2),
WAVE("/wave", 3),
SONOS("/sonos", 4),
SONOS_CACHE("/sonos/*", 5);
companion object {
fun of(id: Int) = values().firstOrNull { it.id == id } ?: UNKNOWN
}
}
object Endpoints {
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
init {
Endpoint.values().forEach {
uriMatcher.addURI("", it.uri, it.id)
}
}
fun match(uri: String) =
Endpoint.of(uriMatcher.match(Uri.parse("content://$uri")))
}

View File

@@ -1,13 +1,13 @@
package io.bartek.ttsserver.web package io.bartek.ttsserver.web.dto
import fi.iki.elonen.NanoHTTPD import fi.iki.elonen.NanoHTTPD
import fi.iki.elonen.NanoHTTPD.ResponseException import fi.iki.elonen.NanoHTTPD.ResponseException
import org.json.JSONObject import org.json.JSONObject
import java.util.* import java.util.*
data class SonosTTSRequestData(val text: String, val language: Locale, val zone: String, val volume: Int) { data class BaseDTO(val text: String, val language: Locale, val zone: String, val volume: Int) {
companion object { companion object {
fun fromJSON(json: String): SonosTTSRequestData { fun fromJSON(json: String): BaseDTO {
val root = JSONObject(json) val root = JSONObject(json)
val language = root.optString("language") val language = root.optString("language")
@@ -24,7 +24,12 @@ data class SonosTTSRequestData(val text: String, val language: Locale, val zone:
) )
val volume = root.optInt("volume", 50) val volume = root.optInt("volume", 50)
return SonosTTSRequestData(text, language, zone, volume) return BaseDTO(
text,
language,
zone,
volume
)
} }
} }
} }

View File

@@ -1,13 +1,13 @@
package io.bartek.ttsserver.web package io.bartek.ttsserver.web.dto
import fi.iki.elonen.NanoHTTPD import fi.iki.elonen.NanoHTTPD
import fi.iki.elonen.NanoHTTPD.ResponseException import fi.iki.elonen.NanoHTTPD.ResponseException
import org.json.JSONObject import org.json.JSONObject
import java.util.* import java.util.*
data class TTSRequestData(val text: String, val language: Locale) { data class SonosDTO(val text: String, val language: Locale) {
companion object { companion object {
fun fromJSON(json: String): TTSRequestData { fun fromJSON(json: String): SonosDTO {
val root = JSONObject(json) val root = JSONObject(json)
val language = root.optString("language") val language = root.optString("language")
@@ -19,7 +19,7 @@ data class TTSRequestData(val text: String, val language: Locale) {
"" ""
) )
return TTSRequestData(text, language) return SonosDTO(text, language)
} }
} }
} }

View File

@@ -0,0 +1,13 @@
package io.bartek.ttsserver.web.endpoint
enum class Endpoint(val uri: String, val id: Int) {
UNKNOWN("/", 1),
SAY("/say", 2),
WAVE("/wave", 3),
SONOS("/sonos", 4),
SONOS_CACHE("/sonos/*", 5);
companion object {
fun of(id: Int) = values().firstOrNull { it.id == id } ?: UNKNOWN
}
}

View File

@@ -0,0 +1,17 @@
package io.bartek.ttsserver.web.endpoint
import android.content.UriMatcher
import android.net.Uri
object EndpointMatcher {
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
init {
Endpoint.values().forEach {
uriMatcher.addURI("", it.uri, it.id)
}
}
fun match(uri: String) =
Endpoint.of(uriMatcher.match(Uri.parse("content://$uri")))
}

View File

@@ -1,4 +1,4 @@
package io.bartek.ttsserver.web package io.bartek.ttsserver.web.server
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -13,6 +13,10 @@ import io.bartek.ttsserver.service.ServiceState
import io.bartek.ttsserver.sonos.SonosQueue import io.bartek.ttsserver.sonos.SonosQueue
import io.bartek.ttsserver.tts.TTS import io.bartek.ttsserver.tts.TTS
import io.bartek.ttsserver.tts.TTSStatus import io.bartek.ttsserver.tts.TTSStatus
import io.bartek.ttsserver.web.dto.BaseDTO
import io.bartek.ttsserver.web.dto.SonosDTO
import io.bartek.ttsserver.web.endpoint.Endpoint
import io.bartek.ttsserver.web.endpoint.EndpointMatcher
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@@ -40,7 +44,7 @@ class WebServer(
} }
private fun dispatch(it: IHTTPSession): Response { private fun dispatch(it: IHTTPSession): Response {
return when (Endpoints.match(it.uri)) { return when (EndpointMatcher.match(it.uri)) {
Endpoint.SAY -> say(it) Endpoint.SAY -> say(it)
Endpoint.WAVE -> wave(it) Endpoint.WAVE -> wave(it)
Endpoint.SONOS -> sonos(it) Endpoint.SONOS -> sonos(it)
@@ -68,7 +72,11 @@ class WebServer(
throw ResponseException(BAD_REQUEST, "") throw ResponseException(BAD_REQUEST, "")
} }
val (text, language) = extractBody(session) { TTSRequestData.fromJSON(it) } val (text, language) = extractBody(session) {
SonosDTO.fromJSON(
it
)
}
tts.performTTS(text, language) tts.performTTS(text, language)
return newFixedLengthResponse(OK, MIME_PLAINTEXT, "") return newFixedLengthResponse(OK, MIME_PLAINTEXT, "")
@@ -94,10 +102,15 @@ class WebServer(
throw ResponseException(BAD_REQUEST, "") throw ResponseException(BAD_REQUEST, "")
} }
val (text, language) = extractBody(session) { TTSRequestData.fromJSON(it) } val (text, language) = extractBody(session) {
SonosDTO.fromJSON(
it
)
}
val (stream, size) = tts.fetchTTSStream(text, language) val (stream, size) = tts.fetchTTSStream(text, language)
return newFixedLengthResponse(OK, MIME_WAVE, stream, size) return newFixedLengthResponse(OK,
MIME_WAVE, stream, size)
} }
private fun sonos(session: IHTTPSession): Response { private fun sonos(session: IHTTPSession): Response {
@@ -113,7 +126,11 @@ class WebServer(
throw ResponseException(BAD_REQUEST, "") throw ResponseException(BAD_REQUEST, "")
} }
val data = extractBody(session) { SonosTTSRequestData.fromJSON(it) } val data = extractBody(session) {
BaseDTO.fromJSON(
it
)
}
sonos.push(data) sonos.push(data)
@@ -139,7 +156,8 @@ class WebServer(
val stream = BufferedInputStream(FileInputStream(file)) val stream = BufferedInputStream(FileInputStream(file))
val size = file.length() val size = file.length()
return newFixedLengthResponse(OK, MIME_WAVE, stream, size) return newFixedLengthResponse(OK,
MIME_WAVE, stream, size)
} }
override fun start() { override fun start() {

View File

@@ -1,4 +1,4 @@
package io.bartek.ttsserver.web package io.bartek.ttsserver.web.server
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
@@ -13,5 +13,10 @@ class WebServerFactory(
private val sonos: SonosQueue private val sonos: SonosQueue
) { ) {
fun createWebServer() = fun createWebServer() =
WebServer(preferences.getInt(PreferenceKey.PORT, 8080), context, preferences, tts, sonos) WebServer(
preferences.getInt(
PreferenceKey.PORT,
8080
), context, preferences, tts, sonos
)
} }