Refactor io.bartek.ttsserver.web package
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
@@ -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")))
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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")))
|
||||||
|
}
|
||||||
@@ -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() {
|
||||||
@@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user