commit 30/10/2025
This commit is contained in:
@@ -33,7 +33,7 @@ lateinit var audioPlayer: AudioPlayer
|
||||
val StreamerOutputs: MutableMap<String, BarixConnection> = HashMap()
|
||||
lateinit var udpreceiver: UDPReceiver
|
||||
lateinit var tcpreceiver: TCPReceiver
|
||||
const val version = "0.0.12 (27/10/2025)"
|
||||
const val version = "0.0.13 (30/10/2025)"
|
||||
// AAS 64 channels
|
||||
const val max_channel = 64
|
||||
|
||||
|
||||
@@ -29,9 +29,11 @@ class BarixConnection(val index: UInt, var channel: String, val ipaddress: Strin
|
||||
fun AddPipeOut(key: String, pipeOut: PipedOutputStream) {
|
||||
RemovePipeOut(key)
|
||||
PipeOuts[key] = pipeOut
|
||||
println("Added pipeOut $key to BarixConnection $channel ($ipaddress)")
|
||||
}
|
||||
|
||||
fun RemovePipeOut(key: String) {
|
||||
println("Removing pipeOut $key")
|
||||
if (PipeOuts.contains(key)){
|
||||
val pipe = PipeOuts[key]
|
||||
try {
|
||||
@@ -39,6 +41,7 @@ class BarixConnection(val index: UInt, var channel: String, val ipaddress: Strin
|
||||
} catch (e: Exception) {
|
||||
// ignore
|
||||
}
|
||||
println("Removed pipeOut $key from BarixConnection $channel ($ipaddress)")
|
||||
PipeOuts.remove(key)
|
||||
}
|
||||
}
|
||||
@@ -148,6 +151,8 @@ class BarixConnection(val index: UInt, var channel: String, val ipaddress: Strin
|
||||
val pp = PipeOuts[kk]
|
||||
try {
|
||||
pp?.write(chunk)
|
||||
pp?.flush()
|
||||
println("Written ${chunk.size} bytes to pipeOut $kk")
|
||||
} catch (e: Exception) {
|
||||
Logger.error { "Failed to write to pipeOut $kk, message: ${e.message}" }
|
||||
pp?.close()
|
||||
|
||||
@@ -55,7 +55,8 @@ import java.nio.file.Path
|
||||
@Suppress("unused")
|
||||
class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val _config: configFile) {
|
||||
|
||||
var app: Javalin? = null
|
||||
lateinit var app: Javalin
|
||||
lateinit var semiauto : Javalin
|
||||
val objectmapper = jacksonObjectMapper()
|
||||
|
||||
private fun SendReply(context: WsMessageContext, command: String, value: String) {
|
||||
@@ -191,7 +192,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e.message!=null && (e.message is String) && e.message!!.isNotEmpty()) {
|
||||
if (e.message != null && (e.message is String) && e.message!!.isNotEmpty()) {
|
||||
Logger.error { "Error processing WebSocket message: ${e.message}" }
|
||||
}
|
||||
}
|
||||
@@ -226,47 +227,56 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
path("overview.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("setting.html"){
|
||||
path("setting.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("streamerstatus.html"){
|
||||
path("streamerstatus.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("timer.html"){
|
||||
path("timer.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("usermanagement.html"){
|
||||
path("usermanagement.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("api") {
|
||||
path("LiveAudio"){
|
||||
get("Open/{broadcastzone}"){ ctx ->
|
||||
//TODO gak jalan
|
||||
path("LiveAudio") {
|
||||
get("Open/{broadcastzone}") { ctx ->
|
||||
val param = ctx.pathParam("broadcastzone")
|
||||
if (param.isNotEmpty()){
|
||||
println("LiveAudio Open for zone $param")
|
||||
if (param.isNotEmpty()) {
|
||||
val bc = Get_Barix_Connection_by_ZoneName(param)
|
||||
if (bc!=null){
|
||||
val key = ctx.req().remoteAddr+":"+ctx.req().remotePort
|
||||
if (bc != null) {
|
||||
val key = ctx.req().remoteAddr + ":" + ctx.req().remotePort
|
||||
val pipeIN = PipedInputStream(8192)
|
||||
val pipeOUT = PipedOutputStream(pipeIN)
|
||||
bc.AddPipeOut(key,pipeOUT)
|
||||
bc.AddPipeOut(key, pipeOUT)
|
||||
ctx.contentType("audio/wav")
|
||||
ctx.header("Cache-Control", "no-cache")
|
||||
ctx.header("Connection", "keep-alive")
|
||||
ctx.result(pipeIN)
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Broadcastzone not found")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid broadcastzone")))
|
||||
println("LiveAudio Open for zone $param SUCCESS")
|
||||
} else ctx.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Broadcastzone not found")))
|
||||
} else ctx.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid broadcastzone")))
|
||||
|
||||
}
|
||||
get("Close/{broadcastzone}"){ ctx ->
|
||||
get("Close/{broadcastzone}") { ctx ->
|
||||
val param = ctx.pathParam("broadcastzone")
|
||||
if (param.isNotEmpty()){
|
||||
println("LiveAudio Close for zone $param")
|
||||
if (param.isNotEmpty()) {
|
||||
val bc = Get_Barix_Connection_by_ZoneName(param)
|
||||
if (bc!=null){
|
||||
val key = ctx.req().remoteAddr+":"+ctx.req().remotePort
|
||||
if (bc != null) {
|
||||
val key = ctx.req().remoteAddr + ":" + ctx.req().remotePort
|
||||
bc.RemovePipeOut(key)
|
||||
ctx.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Broadcastzone not found")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid broadcastzone")))
|
||||
println("LiveAudio Close for zone $param SUCCESS")
|
||||
} else ctx.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Broadcastzone not found")))
|
||||
} else ctx.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid broadcastzone")))
|
||||
}
|
||||
}
|
||||
path("VoiceType") {
|
||||
@@ -1758,7 +1768,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
} else it.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Filename is empty")))
|
||||
}
|
||||
post("PlayPagingResultFile"){
|
||||
post("PlayPagingResultFile") {
|
||||
val json: JsonNode = objectmapper.readTree(it.body())
|
||||
val filename = json.get("filename").asText("")
|
||||
if (filename.isNotEmpty()) {
|
||||
@@ -1805,7 +1815,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
} else it.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Filename is empty")))
|
||||
}
|
||||
post("PlaySoundbankResultFile"){
|
||||
post("PlaySoundbankResultFile") {
|
||||
val json: JsonNode = objectmapper.readTree(it.body())
|
||||
val filename = json.get("filename").asText("")
|
||||
if (filename.isNotEmpty()) {
|
||||
@@ -1820,7 +1830,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
} else it.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Filename is empty")))
|
||||
}
|
||||
get("ListSoundbank/{language}/{voice}/{category}"){
|
||||
get("ListSoundbank/{language}/{voice}/{category}") {
|
||||
val language = it.pathParam("language")
|
||||
val voice = it.pathParam("voice")
|
||||
val category = it.pathParam("category")
|
||||
@@ -1833,9 +1843,9 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
VoiceType.valueOf(voice),
|
||||
Category.valueOf(category)
|
||||
)
|
||||
val result = ListAudioFiles(targetdir).map{ mm ->
|
||||
val result = ListAudioFiles(targetdir).map { mm ->
|
||||
// just the filename, without path
|
||||
mm.substring(mm.lastIndexOf(File.separator)+1)
|
||||
mm.substring(mm.lastIndexOf(File.separator) + 1)
|
||||
}
|
||||
//println("ListSoundbank result: $result")
|
||||
it.result(objectmapper.writeValueAsString(result))
|
||||
@@ -1916,7 +1926,11 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
successfiles.joinToString(
|
||||
", "
|
||||
)
|
||||
}, failed: ${failedfiles.joinToString(", ")}, already exists: ${alreadyexists.joinToString(", ")}"
|
||||
}, failed: ${failedfiles.joinToString(", ")}, already exists: ${
|
||||
alreadyexists.joinToString(
|
||||
", "
|
||||
)
|
||||
}"
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1940,12 +1954,12 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
}
|
||||
}
|
||||
path("Settings") {
|
||||
path("OldResultDays"){
|
||||
path("OldResultDays") {
|
||||
get {
|
||||
it.result(objectmapper.writeValueAsString(resultMessage(_config.Get(configKeys.AUTO_DELETE_RESULT_DAYS.key))))
|
||||
}
|
||||
post {
|
||||
val json : JsonNode = objectmapper.readTree(it.body())
|
||||
val json: JsonNode = objectmapper.readTree(it.body())
|
||||
val days = json.get("days").asInt(3)
|
||||
_config.Set(configKeys.AUTO_DELETE_RESULT_DAYS.key, days.toString())
|
||||
_config.Save()
|
||||
@@ -1953,7 +1967,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
}
|
||||
}
|
||||
path("SoundbankDirectory"){
|
||||
path("SoundbankDirectory") {
|
||||
get {
|
||||
val dir = _config.Get(configKeys.SOUNDBANK_DIRECTORY.key)
|
||||
it.result(objectmapper.writeValueAsString(resultMessage(dir)))
|
||||
@@ -1974,7 +1988,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
}
|
||||
}
|
||||
}
|
||||
path("FISCode"){
|
||||
path("FISCode") {
|
||||
get {
|
||||
val value = object {
|
||||
//get from config file
|
||||
@@ -2019,29 +2033,81 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
|
||||
|
||||
}
|
||||
}
|
||||
}.start(listenPort)
|
||||
}.start(listenPort)
|
||||
semiauto = Javalin.create{ config ->
|
||||
config.useVirtualThreads = true
|
||||
config.staticFiles.add ("/semiauto")
|
||||
config.jsonMapper(JavalinJackson(jacksonObjectMapper()))
|
||||
config.router.apiBuilder {
|
||||
path("/"){
|
||||
get {
|
||||
it.cookie("semiauto-user","")
|
||||
it.redirect("login.html")
|
||||
}
|
||||
}
|
||||
path("logout"){
|
||||
get {
|
||||
it.cookie("semiauto-user","")
|
||||
it.redirect("login.html")
|
||||
}
|
||||
}
|
||||
path("login.html"){
|
||||
post {
|
||||
val formuser = it.formParam("username") ?: ""
|
||||
val formpass = it.formParam("password") ?: ""
|
||||
if (formuser.isNotEmpty() && formpass.isNotEmpty()){
|
||||
val user = db.userDB.List.find { u -> u.username==formuser && u.password==formpass }
|
||||
if (user!=null){
|
||||
it.cookie("semiauto-user",user.username)
|
||||
it.redirect("index.html")
|
||||
} else ResultMessageString(it, 400, "Invalid username or password")
|
||||
} else ResultMessageString(it, 400, "Username or password cannot be empty")
|
||||
}
|
||||
}
|
||||
path("index.html"){
|
||||
before { CheckSemiAutoUsers(it) }
|
||||
}
|
||||
path("log.html"){
|
||||
before { CheckSemiAutoUsers(it) }
|
||||
}
|
||||
}
|
||||
}.start(listenPort+1)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun CheckUsers(ctx: Context) {
|
||||
//val user = ctx.sessionAttribute<String?>("user")
|
||||
val user = ctx.cookie("aas-user")
|
||||
if (user == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
val foundUser = userlist.find { it.first == user }
|
||||
if (foundUser == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
}
|
||||
|
||||
fun Get_Barix_Connection_by_ZoneName(zonename: String) : BarixConnection? {
|
||||
if (ValidString(zonename)){
|
||||
val bz = db.broadcastDB.List.find{ it.description == zonename }
|
||||
val sc = if (bz!=null) db.soundchannelDB.List.find { it.channel == bz.SoundChannel } else null
|
||||
fun ResultMessageString(ctx: Context, code: Int, message: String) {
|
||||
ctx.status(code).result(objectmapper.writeValueAsString(resultMessage(message)))
|
||||
}
|
||||
|
||||
fun CheckSemiAutoUsers(ctx: Context){
|
||||
val user = ctx.cookie("semiauto-user")
|
||||
if (user == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
val foundUser = db.userDB.List.find { u -> u.username==user }
|
||||
if (foundUser == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
}
|
||||
|
||||
fun CheckUsers(ctx: Context) {
|
||||
//val user = ctx.sessionAttribute<String?>("user")
|
||||
val user = ctx.cookie("aas-user")
|
||||
if (user == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
val foundUser = userlist.find { it.first == user }
|
||||
if (foundUser == null) {
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
}
|
||||
|
||||
fun Get_Barix_Connection_by_ZoneName(zonename: String): BarixConnection? {
|
||||
if (ValidString(zonename)) {
|
||||
val bz = db.broadcastDB.List.find { it.description == zonename }
|
||||
val sc = if (bz != null) db.soundchannelDB.List.find { it.channel == bz.SoundChannel } else null
|
||||
val ip = sc?.ip ?: ""
|
||||
if (ValidIPV4(ip)){
|
||||
if (ValidIPV4(ip)) {
|
||||
// ketemu ip-nya
|
||||
return StreamerOutputs[ip]
|
||||
|
||||
@@ -2050,8 +2116,8 @@ fun CheckUsers(ctx: Context) {
|
||||
return null
|
||||
}
|
||||
|
||||
fun Stop() {
|
||||
app?.stop()
|
||||
|
||||
}
|
||||
fun Stop() {
|
||||
app.stop()
|
||||
semiauto.stop()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user